#pragma once
#include "LibGridTIFF/GridTIFF.hpp"
#include "LibDGGSBase/DGGSDefine.hpp"

using namespace NNU::DGGS::Base;
using namespace NNU::DGGS;

# pragma region  PDOP常量声明

// 地球表面最大最小高度
#define minAltitude (-412.0)
#define maxAltitude (8848.0)

//缓冲区大小（弧度 0.05427516220386499）
#define BufferSize (acos((earthRadius*1000.0+minAltitude)/(earthRadius*1000+maxAltitude)))
//缓冲区大小（米）
#define MaxDistance (BufferSize*earthRadius*1000.0)

//GridTIFF的数据大小
#define GridTIFFSize(gridSize) (gridSize * 2 * gridSize * 2)

//层级代码
const char levels[] = "0123456789abcdefghijklmnopqrstuvwxyz";

#pragma endregion

/// <summary>
/// GridTIFF编码
/// </summary>
struct DGGSGridTIFFCode
{
    int basePartition=0;
    int level=0;
    long long morton=0;
    bool operator==(const DGGSGridTIFFCode& other) const {
        return this->basePartition == other.basePartition && this->level == other.level && this->morton == other.morton;
    }
};

/// <summary>
/// 获取GridTIFF编码的字符串格式
/// </summary>
inline std::string getGridTiffString(DGGSGridTIFFCode gridTiffCode, int originLevel)
{
    long long number=gridTiffCode.morton;
    int level=gridTiffCode.level;
    std::string base4;
    if (number == 0)
        base4 ="0";
    while (number > 0) {
        base4 = std::to_string(number % 4) + base4;
        number /= 4;
    }

    int length=0;
    if(level < originLevel + 1)
    {
        return std::to_string(gridTiffCode.basePartition - 1) + levels[gridTiffCode.level];
    }
    else
        length= level - originLevel;

    if (base4.length() < length) {
        base4.insert(0, length - base4.length(), '0');
    }
    std::string result=std::to_string(gridTiffCode.basePartition - 1) + levels[gridTiffCode.level]+base4;
    return result;
}

/// <summary>
/// 获取GridTIFF编码格式
/// </summary>
inline DGGSGridTIFFCode getGridTiffCode(const std::string& GridTiffStr)
{
    DGGSGridTIFFCode gridTiffCode;

    //basePartition
    gridTiffCode.basePartition=GridTiffStr[0]-'0'+1;

    //level
    for (int i = 0; levels[i] != '\0'; i++) {
        if (levels[i] == GridTiffStr[1]) {
            gridTiffCode.level = i ;
            break;
        }
    }

    //morton
    int power = 1;
    for (int i = (int)GridTiffStr.size() - 1; i >= 2; --i)
    {
        int digit = GridTiffStr[i] - '0';
        gridTiffCode.morton += digit * power;
        power *= 4;
    }

    return gridTiffCode;
}

